#ifndef LISTA_H
#define LISTA_H

#include "container.hpp"

template <class T>
class lista : public container<T>
{
public:

	void
	push_back(const T&);

	void
	next();

	void
	previous();

	const bool
	isFirst();

	const bool
	isLast();

	const bool
	find (const T&);

protected:

	noh<T>*
	findFirst();

};


/***********************************************
 * 
 *        Implementations...
 * 
 * *********************************************/

template<class T> void
lista<T>::push_back(const T& _info)
{
	noh<T>*
	newNoh = new noh<T>(_info);
	
	if (this->cursor == 0)
	{
		this->cursor = newNoh;
	}
	else if (this->cursor->getPosterior() != 0)
	{
		noh<T>*
		nohPosterior = this->cursor->getPosterior();
	
		newNoh->setAnterior(this->cursor);
		newNoh->setPosterior(nohPosterior);
		
		nohPosterior->setAnterior(newNoh);
		
		this->cursor->setPosterior(newNoh);
		
		this->cursor = newNoh;
	}

}

template<class T> void
lista<T>::previous()
{
	if (this->cursor->getPosterior() != 0)
	{
		this->cursor = this->cursor->getPosterior();
	}
	else
	{
		const std::string
		message = "ops.. trying to iterate with an empty list!";
		
		error*
		e = new error(message);
		
		throw e;
	}
}

template<class T> void 
lista<T>::next()
{
	if (this->cursor->getAnterior() != 0)
	{
		this->cursor = this->cursor->getAnterior();
	}
	else
	{
		const std::string
		message = "ops.. trying to iterate with an empty list!";
		
		error*
		e = new error(message);
		
		throw e;
	}
	
}

template<class T> const bool
lista<T>::isFirst()
{
	if (this->cursor->getAnterior() == 0)
		return true;
	return false;
}

template<class T> const bool
lista<T>::isLast()
{
	if (this->cursor->getPosterior() == 0)
		return true;
	return false;
}

template<class T> const bool
lista<T>::find(const T& _info)
{
	noh<T>*
	temp = this->findFirst();
	
	while (temp != 0)
	{
		if( temp->getInfo() == _info)
		{
			this->cursor = temp;
			return true;
		}
		temp = temp->getPosterior();
	}
	
	return false;
}

/***************************
 * 
 *  Protected Methods
 * 
 * *************************/

template<class T> noh<T>*
lista<T>::findFirst()
{
	noh<T>*
	temp = this->cursor;
	
	
	while (temp->getAnterior() != 0)
		temp = temp->getAnterior();
	
	return temp;
}

#endif /* LISTA_H */
